package kd.hc.utils;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.dataentity.metadata.dynamicobject.DynamicLocaleProperty;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.property.*;
import kd.bos.form.IFormView;
import kd.bos.id.ID;

import java.util.*;
import java.util.stream.Collectors;

public class SourceBillToCurrentBill {

    public static Set<String> getDefaultIgnoreFields() {
        Set<String> ignoreFields = new HashSet();
        ignoreFields.add("id");
        ignoreFields.add("pid");
        ignoreFields.add("billstatus");
        ignoreFields.add("auditor");
        ignoreFields.add("auditdate");
        ignoreFields.add("creator");
        ignoreFields.add("createtime");
        ignoreFields.add("modifier");
        ignoreFields.add("modifytime");
        return ignoreFields;
    }


    public static void initSourceData(IFormView view, IDataModel dataModel, DynamicObject source, Set<String> ignoreFields) {
        if (ignoreFields == null) {
            ignoreFields = getDefaultIgnoreFields();
        }
        MainEntityType dataEntityType = EntityMetadataCache.getDataEntityType(view.getFormShowParameter().getFormId());
        DataEntityPropertyCollection properties = dataEntityType.getProperties();
        DynamicObjectType projectType = source.getDynamicObjectType();
        Iterator var6 = properties.iterator();

        while (var6.hasNext()) {
            IDataEntityProperty property = (IDataEntityProperty) var6.next();
            if (property instanceof EntryProp) {
                handleEntry(view, dataModel, property, source, ignoreFields);
            } else if (!handleSomeFields(dataModel, property, source)) {
                String name = property.getName();
                if (!name.endsWith("_id") && !ignoreFields.contains(name) && projectType.getProperty(name) != null) {
                    dataModel.setValue(name, source.get(name));
                }
            }
        }
        dataModel.updateCache();
    }

    public static void handleEntry(IFormView view, IDataModel dataModel, IDataEntityProperty property, DynamicObject source, Set<String> ignoreFields) {
        String formId = view.getFormShowParameter().getFormId();
        EntryProp entryProp = (EntryProp) property;
        Set<String> ignoreFieldsNew = new HashSet<>(ignoreFields);
        if (property instanceof TreeEntryProp) {
            ignoreFieldsNew.remove("id");
            ignoreFieldsNew.remove("pid");
        }

        DynamicObjectType entryType = entryProp.getDynamicCollectionItemPropertyType();
        if (entryType != null) {
            DataEntityPropertyCollection entryProps = entryType.getProperties();
            DynamicObjectCollection billEntry = dataModel.getEntryEntity(property.getName());
            DynamicObjectCollection sourceEntry = source.getDynamicObjectCollection(property.getName());
            DynamicObjectType sourceType = sourceEntry.getDynamicObjectType();
            Iterator var11 = sourceEntry.iterator();
            HashMap<String, Long> treeIdNew = new HashMap<>();
            if (property instanceof TreeEntryProp) {
                List<String> pkList = sourceEntry.stream().map(m1 -> m1.getPkValue().toString()).collect(Collectors.toList());
                pkList.forEach(item -> {
                    long newId = ID.genLongId();
                    treeIdNew.put(item, newId);
                });
            }

            while (var11.hasNext()) {
                DynamicObject entity = (DynamicObject) var11.next();
                DynamicObject entry = billEntry.addNew();
                entry = handleEntryDefault(view, property.getName(), entry, entity);
                Iterator var14 = entryProps.iterator();
                while (var14.hasNext()) {
                    IDataEntityProperty prop = (IDataEntityProperty) var14.next();
                    String name = prop.getName();
                    if (!ignoreFieldsNew.contains(name) && sourceType.getProperty(name) != null) {
                        if (prop instanceof SubEntryProp) {//子单据体
                            DynamicObjectCollection subEntity = (DynamicObjectCollection) entity.get(prop.getName());
                            handleSubEntry(view, dataModel, prop, entry, subEntity, ignoreFields);
                        } else {
                            entry.set(prop.getName(), entity.get(prop.getName()));
                            if (property instanceof TreeEntryProp) {
                                if ("id".equals(name) || "pid".equals(name)) {
                                    entry.set(prop.getName(), treeIdNew.get(entity.get(prop.getName()).toString()));
                                }
                                if ("hc95_target_costupdate".equals(formId) && "hc95_tree_entryentity".equals(property.getName()) && "hc95_longid_en".equals(name)) {
                                    entry.set("hc95_longid_en", handTreeEntityLongId(treeIdNew, entity.get(prop.getName())));
                                }
                            }
                        }
                    }

                }
            }

            dataModel.updateEntryCache(billEntry);
            view.updateView(property.getName());
        }

    }

    public static String handTreeEntityLongId(HashMap<String, Long> treeIdNew, Object longId) {
        String newLongIds = "";
        if (longId != null) {
            String longIdStr = longId.toString();
            String[] longIdArr = longIdStr.split("\\.");
            if (longIdArr != null && longIdArr.length >= 1) {
                for (String idRow : longIdArr) {
                    newLongIds = newLongIds + treeIdNew.get(idRow) + ".";
                }
                newLongIds = newLongIds.substring(0, newLongIds.length() - 1);
            } else {
                newLongIds = treeIdNew.get(longIdStr) + "";
            }
        }
        return newLongIds;
    }

    public static DynamicObject handleEntryDefault(IFormView view, String entityKey, DynamicObject entryNewRow, DynamicObject entitySourceRow) {
        String formId = view.getFormShowParameter().getFormId();
        if ("hc95_target_costupdate".equals(formId) && "hc95_tree_entryentity".equals(entityKey)) {
            entryNewRow.set("hc95_oldmbcbmx_id", entitySourceRow.get("id"));
        }
        if ("hc95_target_costupdate".equals(formId) && "hc95_building_all".equals(entityKey)) {
            entryNewRow.set("hc95_oldmbcbmx_ldid", entitySourceRow.get("id"));
        }
        if ("hc95_target_costupdate".equals(formId) && "hc95_building_zb".equals(entityKey)) {
            entryNewRow.set("hc95_oldmbcbmx_zbid", entitySourceRow.get("id"));
        }
        return entryNewRow;
    }


    public static void handleSubEntry(IFormView view, IDataModel dataModel, IDataEntityProperty property, DynamicObject entryParent, DynamicObjectCollection sourceSubEntry, Set<String> ignoreFields) {
        String formId = view.getFormShowParameter().getFormId();
        Set<String> ignoreFieldsNew = new HashSet<>(ignoreFields);
        if (property instanceof TreeEntryProp) {
            ignoreFieldsNew.remove("id");
            ignoreFieldsNew.remove("pid");
        }
        SubEntryProp entrySubProp = (SubEntryProp) property;
        DynamicObjectType entrSubType = entrySubProp.getDynamicCollectionItemPropertyType();
        if (entrSubType != null) {
            DataEntityPropertyCollection entrySubProps = entrSubType.getProperties();
            DynamicObjectCollection billSubEntry = entryParent.getDynamicObjectCollection(property.getName());
            DynamicObjectType sourceType = sourceSubEntry.getDynamicObjectType();
            Iterator var11 = sourceSubEntry.iterator();

            HashMap<String, Long> treeIdNew = new HashMap<>();
            if (property instanceof TreeEntryProp) {
                List<String> pkList = billSubEntry.stream().map(m1 -> m1.getPkValue().toString()).collect(Collectors.toList());
                pkList.forEach(item -> {
                    long newId = ID.genLongId();
                    treeIdNew.put(item, newId);
                });
            }

            while (var11.hasNext()) {
                DynamicObject entity = (DynamicObject) var11.next();
                DynamicObject entry = billSubEntry.addNew();
                entry = handleEntryDefault(view, entrySubProp.getName(), entry, entity);
                Iterator var14 = entrySubProps.iterator();

                while (var14.hasNext()) {
                    IDataEntityProperty prop = (IDataEntityProperty) var14.next();
                    String name = prop.getName();
                    if (!ignoreFieldsNew.contains(name) && sourceType.getProperty(name) != null) {
                        entry.set(prop.getName(), entity.get(prop.getName()));
                        if (property instanceof TreeEntryProp) {
                            if ("id".equals(name) || "pid".equals(name)) {
                                entry.set(prop.getName(), treeIdNew.get(entity.get(prop.getName()).toString()));
                            }
                        }
                    }
                }
            }
            dataModel.updateEntryCache(billSubEntry);
            view.updateView(property.getName());
        }

    }


    public static boolean handleSomeFields(IDataModel dataModel, IDataEntityProperty property, DynamicObject source) {
        boolean flag = false;
        if (property instanceof DynamicLocaleProperty) {
            flag = true;
        } else if (property instanceof MulBasedataProp) {
            DynamicObjectCollection sourceMultiData = source.getDynamicObjectCollection(property.getName());
            DynamicObjectCollection multiData = (DynamicObjectCollection) dataModel.getValue(property.getName());
            multiData.addAll(sourceMultiData);
            dataModel.setValue(property.getName(), multiData);
            flag = true;
        } else if (property instanceof ItemClassProp) {
            ItemClassProp itemClassProp = (ItemClassProp) property;
            String typeName = itemClassProp.getTypePropName();
            dataModel.setValue(typeName, source.get(typeName));
            dataModel.setValue(property.getName(), source.get(property.getName()));
            flag = true;
        } else if (property instanceof ItemClassTypeProp) {
            flag = true;
        }

        return flag;
    }


}
